package com.freewater.springboot.demo.aop.pointcuts;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

/**
 * execution
 * 用于匹配方法执行，最常用。
 * 格式说明
 * execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)
 * throws-pattern?)
 * <p>
 * 1、其中带 ?号的 modifiers-pattern?，declaring-type-pattern?，throws-pattern?是可选项
 * 2、ret-type-pattern,name-pattern, parameters-pattern是必选项
 * 3、modifier-pattern? 修饰符匹配，如public 表示匹配公有方法，*表示任意修饰符
 * 4、ret-type-pattern 返回值匹配，* 表示任何返回值，全路径的类名等
 * 5、declaring-type-pattern? 类路径匹配
 * 6、name-pattern 方法名匹配，* 代表所有，xx*代表以xx开头的所有方法
 * 7、(param-pattern) 参数匹配，指定方法参数(声明的类型)，(..)代表所有参数，(*,String)代表第一个参数为任何值,第二个为String类型，(..,String)代表最后一个参数是String类型
 * 8、throws-pattern? 异常类型匹配
 * <p>
 * 链接：<a href="https://juejin.cn/post/7077425331954515999">Spring系列25：Spring AOP 切点详解</a>
 */
@Aspect
public class PointcutExecution {
    // com.crab.spring.aop.demo02包下任何类的任意方法
    @Pointcut("execution(* com.crab.spring.aop.demo02.*.*(..))")
    public void m1() {
    }

    // com.crab.spring.aop.demo02包及其子包下任何类的任意方法
    @Pointcut("execution(* com.crab.spring.aop.demo02..*.*(..))")
    public void m2() {
    }

    // com.crab.spring.aop包及其子包下IService接口的任意无参方法
    @Pointcut("execution(* com.crab.spring.aop..IService.*(..))")
    public void m3() {
    }

    // com.crab.spring.aop包及其子包下IService接口及其子类型的任意无参方法
    @Pointcut("execution(* com.crab.spring.aop..IService+.*(..))")
    public void m4() {
    }

    // com.crab.spring.aop.demo02.UserService类中有且只有一个String参数的方法
    @Pointcut("execution(* com.crab.spring.aop.demo02.UserService.*(String))")
    public void m5() {
    }

    // com.crab.spring.aop.demo02.UserService类中参数个数为2且最后一个参数类型是String的方法
    @Pointcut("execution(* com.crab.spring.aop.demo02.UserService.*(*,String))")
    public void m6() {
    }

    // com.crab.spring.aop.demo02.UserService类中最后一个参数类型是String的方法
    @Pointcut("execution(* com.crab.spring.aop.demo02.UserService.*(..,String))")
    public void m7() {
    }
}
